package com.itxiuyixiu.tools.common.error.handlers;

import com.itxiuyixiu.tools.util.returns.ReturnVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.convert.ConversionFailedException;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Set;

/**
 * @author 黄磊
 * @date 2020/1/13
 */
@ControllerAdvice
public class MyExceptionHandlers {
    Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 参数缺失的全局处理方法
     *
     * @param ex 异常
     * @return 返回信息
     */
    @ResponseBody
    @ExceptionHandler(value = {MissingServletRequestParameterException.class})
    public ReturnVo paramMissHandler(Exception ex) {
        return new ReturnVo(HttpStatus.BAD_REQUEST, ex.getMessage());
    }

    /**
     * 参数验证失败的全局处理方法
     *
     * @param ex 异常
     * @return 返回信息
     */
    @ResponseBody
    @ExceptionHandler(value = ConstraintViolationException.class)
    public ReturnVo constraintViolationHandler(ConstraintViolationException ex) {
        StringBuilder stringBuilder = new StringBuilder();
        Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations();
        for (ConstraintViolation<?> cvl : constraintViolations) {
            stringBuilder.append(cvl.getMessageTemplate()).append('\n');
        }
        return new ReturnVo(HttpStatus.BAD_REQUEST, stringBuilder.toString());
    }

    /**
     * 参数类型转化失败
     *
     * @param ex 异常
     * @return 返回信息
     */
    @ResponseBody
    @ExceptionHandler(value = MethodArgumentTypeMismatchException.class)
    public ReturnVo constraintViolationHandler(MethodArgumentTypeMismatchException ex) {
        return new ReturnVo(HttpStatus.BAD_REQUEST, ex.getName() + "格式不正确");
    }

    /**
     * 参数转化失败
     *
     * @param ex 异常
     * @return 返回信息
     */
    @ResponseBody
    @ExceptionHandler(value = ConversionFailedException.class)
    public ReturnVo conversionFailedExceptionHandler(ConversionFailedException ex) {
        return new ReturnVo(HttpStatus.BAD_REQUEST, "将" + ex.getValue() + "从" + ex.getSourceType().getName() + "转化为" + ex.getTargetType().getName() + "失败");
    }

    /**
     * 数据没有被找到的异常
     *
     * @param ex 异常
     * @return 返回信息
     */
    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public ReturnVo errorHandler(Exception ex) {
        logger.error(ex.getMessage());
        ex.printStackTrace();
        return new ReturnVo(HttpStatus.BAD_REQUEST, ex.getMessage());
    }
}
